class XChatUser {
  constructor() {
    this.ws = null;
    this.userId = this.generateUserId();
    this.nickname = this.loadNickname();
    this.users = new Map();
    this.onlineCallback = null;
    this.offlineCallback = null;
    this.messageCallback = null;
    this.fileOfferCallback = null;
    this.fileProgressCallback = null;
    this.roomPasswordRequired = false;
    
    // 文件传输相关
    this.fileQueue = new Map();
    this.currentFileTransfer = null;
    this.chunkSize = 1024 * 1024; // 1MB
  }

  generateUserId() {
    return 'user_' + Math.random().toString(36).substr(2, 9);
  }

  loadNickname() {
    return localStorage.getItem('nickname') || '用户' + Math.random().toString(36).substr(2, 4);
  }

  saveNickname(nickname) {
    this.nickname = nickname;
    localStorage.setItem('nickname', nickname);
    if (this.ws && this.ws.readyState === WebSocket.OPEN) {
      this.ws.send(JSON.stringify({
        type: 'nickname',
        nickname: nickname
      }));
    }
  }

  connect(serverUrl = `ws://${location.host}`) {
    return new Promise((resolve, reject) => {
      this.ws = new WebSocket(serverUrl);

      this.ws.onopen = () => {
        console.log('WebSocket connected');
        this.ws.send(JSON.stringify({
          type: 'join',
          userId: this.userId,
          nickname: this.nickname
        }));
        resolve();
      };

      this.ws.onclose = () => {
        console.log('WebSocket disconnected');
        setTimeout(() => this.connect(serverUrl), 3000);
      };

      this.ws.onerror = (error) => {
        console.error('WebSocket error:', error);
        reject(error);
      };

      this.ws.onmessage = (event) => {
        const data = JSON.parse(event.data);
        this.handleMessage(data);
      };
    });
  }

  handleMessage(data) {
    switch (data.type) {
      case 'users':
        this.users = new Map(data.users);
        if (this.onlineCallback) this.onlineCallback(Array.from(this.users.values()));
        break;

      case 'join':
        this.users.set(data.userId, {
          userId: data.userId,
          nickname: data.nickname
        });
        if (this.onlineCallback) this.onlineCallback(Array.from(this.users.values()));
        break;

      case 'leave':
        this.users.delete(data.userId);
        if (this.offlineCallback) this.offlineCallback(data.userId);
        break;

      case 'message':
        if (this.messageCallback) this.messageCallback(data);
        break;

      case 'nickname':
        if (this.users.has(data.userId)) {
          const user = this.users.get(data.userId);
          user.nickname = data.nickname;
          if (this.onlineCallback) this.onlineCallback(Array.from(this.users.values()));
        }
        break;

      case 'file_offer':
        if (this.fileOfferCallback) this.fileOfferCallback(data);
        break;

      case 'file_chunk':
        this.handleFileChunk(data);
        break;

      case 'file_complete':
        this.handleFileComplete(data);
        break;

      case 'room_password_required':
        this.roomPasswordRequired = true;
        if (this.passwordRequiredCallback) this.passwordRequiredCallback();
        break;

      case 'room_password_result':
        if (data.success) {
          this.roomPasswordRequired = false;
          if (this.passwordSuccessCallback) this.passwordSuccessCallback();
        } else {
          if (this.passwordErrorCallback) this.passwordErrorCallback();
        }
        break;
    }
  }

  sendMessage(content, toUserId = null) {
    if (this.ws && this.ws.readyState === WebSocket.OPEN) {
      this.ws.send(JSON.stringify({
        type: 'message',
        content,
        toUserId
      }));
    }
  }

  sendFile(file, toUserId) {
    return new Promise((resolve, reject) => {
      const reader = new FileReader();
      reader.onload = () => {
        const arrayBuffer = reader.result;
        const fileId = Math.random().toString(36).substr(2);
        
        // 将文件加入队列
        this.fileQueue.set(fileId, {
          file,
          arrayBuffer,
          toUserId,
          resolve,
          reject
        });

        // 发送文件提议
        this.ws.send(JSON.stringify({
          type: 'file_offer',
          fileId,
          fileName: file.name,
          fileSize: file.size,
          toUserId
        }));
      };
      reader.readAsArrayBuffer(file);
    });
  }

  acceptFile(fileId) {
    this.ws.send(JSON.stringify({
      type: 'file_accept',
      fileId
    }));
  }

  rejectFile(fileId) {
    this.ws.send(JSON.stringify({
      type: 'file_reject',
      fileId
    }));
  }

  handleFileChunk(data) {
    if (this.currentFileTransfer) {
      this.currentFileTransfer.chunks.push(data.chunk);
      this.currentFileTransfer.receivedSize += data.chunk.length;

      if (this.fileProgressCallback) {
        this.fileProgressCallback({
          fileId: data.fileId,
          fileName: this.currentFileTransfer.fileName,
          progress: this.currentFileTransfer.receivedSize / this.currentFileTransfer.fileSize
        });
      }
    }
  }

  handleFileComplete(data) {
    if (this.currentFileTransfer) {
      const blob = new Blob(this.currentFileTransfer.chunks);
      const url = URL.createObjectURL(blob);
      
      if (this.fileCompleteCallback) {
        this.fileCompleteCallback({
          fileId: data.fileId,
          fileName: this.currentFileTransfer.fileName,
          url
        });
      }

      this.currentFileTransfer = null;
    }
  }

  submitRoomPassword(password) {
    if (this.ws && this.ws.readyState === WebSocket.OPEN) {
      this.ws.send(JSON.stringify({
        type: 'room_password',
        password
      }));
    }
  }

  onOnline(callback) {
    this.onlineCallback = callback;
  }

  onOffline(callback) {
    this.offlineCallback = callback;
  }

  onMessage(callback) {
    this.messageCallback = callback;
  }

  onFileOffer(callback) {
    this.fileOfferCallback = callback;
  }

  onFileProgress(callback) {
    this.fileProgressCallback = callback;
  }

  onFileComplete(callback) {
    this.fileCompleteCallback = callback;
  }

  onPasswordRequired(callback) {
    this.passwordRequiredCallback = callback;
  }

  onPasswordSuccess(callback) {
    this.passwordSuccessCallback = callback;
  }

  onPasswordError(callback) {
    this.passwordErrorCallback = callback;
  }
}

// 导出实例
window.xchatuser = new XChatUser(); 